/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Bitmap;
import android.graphics.Point;
import java.util.ArrayList;
/**
 * 20181109: define the interface of Eink PW.
 *
 */

//  abstract class
public interface EinkPWInterface {

    public static final String TAG = "EinkPW-1.0.0";

    public static final boolean DEBUG = true;

//	static int 			mInstanceCount = 0;
//	int 				mId = 0;
//	final Surface mSurface = new Surface();
//	public Rect mWindowFrame = new Rect();
//	public Rect mSurfaceFrame = new Rect();

	/**
	 * 20171115,set Min Width = 0,means Only 1 pixel width,no Press/Speed.
	 * 20180317,it's better to set width as odd number.like 0,1,3,5,7,9
	*/
	public static final int 	MAX_PEN_WIDTH_PIXEL = 9;
	public static final int 	MIN_PEN_WIDTH_PIXEL = 0;

	public static final int 	WT_TYPE_UNKNOW 		= -1;
	public static final int 	WT_TYPE_NONE 		= WT_TYPE_UNKNOW;
	public static final int 	WT_TYPE_INTERSECTED = 0;
	public static final int 	WT_TYPE_MATTS 		= 1;
	public static final int 	WT_TYPE_LINEFIGURE 	= 2;
	public static final int 	WT_TYPE_SINGLELINE 	= 3;

	public static final int 	WT_DEFAULT_PDSIZE 	= 60;

	public static final int 	DRAW_OBJ_RANDOM = 0; // pen-write.
	public static final int 	DRAW_OBJ_LINE = 1; // DRAW line
	public static final int 	DRAW_OBJ_TRIANGLE = 2; // draw triangle
	public static final int 	DRAW_OBJ_CIRCLE = 3; // draw circle
	public static final int 	DRAW_OBJ_RECTANGLE = 4; // draw rectangle.
	public static final int 	DRAW_OBJ_ERASE = 5;	// erase
	public static final int 	DRAW_OBJ_UNDO = 6;
	public static final int 	DRAW_OBJ_MAX = DRAW_OBJ_UNDO;	// the max obj type.

	public String getObjTypeString(int objType);

	/**
	 * 20180317,add repaint speed type to ctrl repaint.
	 */
	public static final int RP_SPEED_X1 = 1;   // speed = orinal speend
	public static final int RP_SPEED_X2 = 2;  // speed = orinal speend *2
	public static final int RP_SPEED_X3 = 2;  // speed = orinal speend *3
	public static final int RP_SPEED_S2 = 11;  // SPEED = original speed /2( more low)
	public static final int RP_SPEED_S3 = 12;  // SPEED = original speed /3( more low)
	public static final int RP_SPEED_S4 = 13;  // SPEED = original speed /4( more low)
	public static final int RP_SPEED_NOWAIT = 20; // speed = no-wait,draw all one time.
	public static final int RP_SPEED_WAIT = 21; // speed = no-wait,draw all one time.

	public static int RP_DEFAULT_DELAY_MS = 2018; // max delay between points.
	public static int RK_UNLIMIT_DELAY_MS = 0X7FFFFFFF;
	public interface RepaintListener {
		//called when repaint finish or be stopped.
		void onRepaintDone(boolean cancel);
	}

	// 20180328,add save bitmap done listener.
    public interface PWSaveBitmapListener {
    	public void saveDone(String pngFilePath); // the filePath is pngFilePath.
    }

	// 2018531,hsl add for Load/save bitmap listener.
    public interface PWLSBitmapListener extends PWSaveBitmapListener{
    	// the filePath is png filePath,pngValid:false means the png is Not fix the tch.
    	public void loadPngDone(String filePath, boolean pngValid);

    	// the filePath is tch filePath.
    	public void loadTchDone(String filePath, boolean pngValid);

    	public void saveAllDone(String pngFilePath, String tchFilePath);
    }

    // 20181220,add for PWTouch Event.
    public interface PWTouchEventListener {
    	public void onPWTouchEvent(MotionEvent event);
    }

	/**
	 *
	 * @author hsl@htfyun.com.cn
	 *
	 * the event listener of the PenDrawView .
	 *
	 * 20170928,change the parameter,we only need is dirtyRect and Bitmap.
	 */
	public interface PWDrawEvent {

		// may use this to perform undo. or save/load
		// 20180331,add erase flag at start.
		public void onTouchDrawStart(Bitmap pwBitmap, boolean erase);

		//20180527,pointArray maybe null.
		public void onTouchDrawEnd(Bitmap pwBitmap, Rect dirtyRect, ArrayList<Point> pointArray);

		public void onOneWordDone(Bitmap pwBitmap, Rect dirtyRect);
	}

	// 20180608,hsl,add for iflytek new request.
	public interface PWEraseEventListener {

		// the event maybe ACTION_HOVER_ENTER/ACTION_HOVER_EXIT/ACTION_HOVER_MOVE.
		// return true: don't do erasing. false: do erase by pw!
		public boolean onEraseEvent(MotionEvent event, boolean click);

		// call when erasing operation done.
		public void onEraseDone(Bitmap pwBitmap, Rect dirtyRect);
	}

	// 20170530,hsl,add for LOG.
	public void OSULOG(String logs, boolean printStack);


	// 20180203,hsl.add dispatch the MotionEvent to Host View.
    public static int 	DISPATH_TOUCH_HOST_NONE			= 0;

    // 20180827: we don't support this function!!
    @Deprecated
    public static int 	DISPATH_TOUCH_HOST_FIRST		= 1;
    public static int 	DISPATH_TOUCH_HOST_LATER		= 2;

	// 20180313,sometimes,we need to drop all touch( when write a lot of).
    public static int 	DISPATH_TOUCH_ALL_DROP			= 4;

	/**
	 * 20170620,we use onInit to set some flag before create window.
	 * like weather we need our own input handle?? -- requestInputReceiver
	 * 20180130: the onInit may be overrided,so mDrawCtrl maybe null.
	 * 20180310: child-class must implement it's own onInit.
	 */
	//public void onInit(Context context);


	// 20180610,hsl,mainly for DEMO-APK.
	// cannot access framework.class.protected varial.
	public int getSeqId();

    public void enableTouchDispatch(int dispatchType);

	public int getTouchDispatch();

    public void disableTouchInput(boolean disable);

    /**
	 * 20180202,hsl add for No Host Support.
	 * we can use the View.setBackgroundColor to set the backGroud.
	 */
	//public int getBackGroudColor();

	/**
	 * 20170620,get the Canvas for Drawing.because the postCanvasFast don't
	 * destroy the canvas,so we need to use mCanvas to record!!
	 * @hide
	 */
	public abstract Canvas lockCanvasFast();

	/**
     * add by hsl for partial fast update
     * 20180125,add new parameter: boolean erasing,
     * is erasing,we use EINK_SHOW_MODE_DU instead.
     * @param canvas The canvas previously obtained from {@link #lockCanvasFast}.
     * 		  dirty: the dirty rect,maybe null( full update ).
     * @hide
     */
    public abstract void postCanvasFast(Canvas canvas, Rect dirty, boolean erasing) ;

	/**
     * 20171108,post full(switch the Surface graphic buffer).
     * 20171209:we need to post to queue buffer,but Don't need to display.
     * @param canvas The canvas previously obtained from {@link #lockCanvasFast}.
     * @hide
     */
    public abstract void postCanvas(Canvas canvas, boolean drop);

	/**
	 * 20180110,sync surface to display to TFT screen.
	 * mainly for test!
	 */
	public void syncSurfaceDisplay();

	// 20180623,hsl add for fc-ctrl.
	public abstract void setEinkFCMode(boolean on);


    /**
	 * 20171107,hsl add.
	 * we can add a bat-dirty Rects,and post one time.
	 * 20171202,add return value.if true: add or,false: add failed.
	 * @param post if true,will post all dirty Rect before setting.
	 * @hide
	 */
    public abstract boolean addOneDirtyRect(Rect dirty, boolean post, boolean noData,
                                            boolean erasing, boolean noDisplay) ;

	/**
	 * 20171128,hsl add for multi Rect Update when PW.
	 * 20171202:maybe Add DataRect Ok,but Add DisplayRect Failed.
	 * but We can't add Bound First.because it will PostCanvas.
	 * 20171207,hsl,if only one Rect,we add one.
	 * XXX: we will call fastpost with dirty is the Bounds.
	 */
    public abstract boolean addDirtyRects(RectArray rects, boolean erasing);

    public abstract void invalidateHost(Rect rect);


	/**
	 * 20171208,get the current host view dirty Rect
	 * when host draw.
	 * HAVE BUG: maybe the hostview's child view update.so
	 * we can't trace the real dirty Rect.at this case,we return
	 * mSurfaceFrame(the hold view ).
	 * return is not null.
	 * 20180310,the host dirty may have many rects at one time.
	 * for perfermance ,we don't union it.
	 * @hide
	*/
    @Deprecated
    public ArrayList<Rect> getHostViewDirty();

	// 20180616,hsl: set the pw-mode(default is DU).
    @Deprecated
	public void setEinkPWMode(short Mode);

	//20180602,hsl:some view have gray when erasing,we can not use A2/DU mode.
	public void setEinkEraseMode(short Mode);

	//20180614,hsl:set A2-GATE for some gray-background case.
	public void setEinkA2Gate(int gate);

	//20180616,hsl: set the Erase A2-GETE.
	public void setEinkEraseA2Gate(int gate);

	// 20180723,hsl: for gray erase support,use with multi-pw-view.
	// we may set one pw-view is all gray erase or just one rect of the view.
	// if grayRect is null, means all this pw-view is gray-erase.
	public void setGrayEraseRect(Rect grayRect);

    /**
	 * 20170912,set the Host View,and our pen-write
	 * content is attach to it by ViewOverlay
	 * 20180318,removee the parameter:loadSaveFilePath and comment.
	 * we use dedicate function: setLoadFilePath
 	*/
	@Deprecated
    public void setHostView(View host/*, String loadSaveFilePath, boolean comment*/);

	// 20180624,hsl: set the host view,and tell the pw that: the host view is
	// just a pure-white blackground.
	/*@Deprecated
	public void setHostView(View host, boolean pureWhite);*/

    // 20181110: hsl add.
    public void onHostViewEnableChanged(boolean enabled);

    // 20181113,hsl add.
    public void onHostViewVisibleChanged(boolean visible);

    // 20181112: hsl add.internal use??
    public void onHostViewAttachedToWindow();
    public void onHostViewDetachedFromWindow();

	/**
	 * 20170920,get the current host view.
	 * maybe null.
	 *
	*/
    public abstract View getHostView();

	// public boolean isSurfaceHardwareAccl();

	// 20180816: AInote needs this Function.
	@Deprecated
    public Rect getWinFrame();

	// 20180722,hsl: for multi-pw-surface scrolling.
	public void setScrollView(View scollView);

	public void setScrollRect(Rect scrollRect);

	// 2018021,return the total pw-area rect.
	public Rect getScrollRect();

	// 20180816: call when scroll changed!!
	//@Deprecated
	// public void updateSurfaceOffset();

    /**
     * 20180224,add default dir path for save/load.
     * we also save the pointers.
     * 20180318:add paramter: display the bitmap now??
     */
    public abstract void setLoadFilePath(String filePath, boolean display);

	public abstract void setLoadFilePathWithListener(String filePath, boolean display,
                                                     PWLSBitmapListener listener);

    public abstract String getPWTouchFilePath();

    public abstract String getPWBitmapFilePath();

    @Deprecated
    public void setNeedSaveFiles(boolean needed);

    @Deprecated
    public boolean getNeedSaveFiles();


	// 20180401,sometimes we don't need erasing,like pw-input.
	public void disablePenErase(boolean disable);

	public boolean isPenEraseDisable();

	// 20180404,hsl add.default is display.
	public void dispalyPWBitmapOnGone(boolean display);

    /*------------START:the interface for HOST activity to set pen-----*/
	public abstract int setPenSettingWidth(int pixelWidth);

	public abstract int getPenSettingWidth();

	public abstract int setPenEraseWidth(int pixelWidth);

	public abstract int getPenEraseWidth();

	/*
	 * 20171222,we use draw object to instead the pem mode.
	public void setPenMode(int mode) {
		// TODO Auto-generated method stub
		mPen.setPenMode(mode);
	}

	public int getPenMode() {
		// TODO Auto-generated method stub
		return mPen.getPenMode();
	}*/

	public float getPenAdjRate();

 	/*------ END:the interface for surface for PW -------*/
	public void setDrawEventListener(PWDrawEvent listener);

	public void setEraseEventListener(PWEraseEventListener listener);

    // 20181220,hsl add.
    public void setPWTouchEventListener(PWTouchEventListener listener);

	/**
	 * 20180318,add parameter:clearTouch when clear the pw-bitmap.
	 * we may just clear bitmap but not clear the touchs for repaint.
	 */
	public abstract void clearContent(Rect rect, boolean post, boolean clearTouch);

	@Deprecated
	public abstract void clearContent(Rect rect, boolean post, boolean clearTouch, boolean force);

    // 20181220:when no SurfaceView,we need to hide the PW-Function.
    public abstract void setPWEnabled(boolean enabled);

	public abstract Bitmap getPureWriteBitmap() ;

    // 20181220:for compitbale!!
    public abstract Bitmap getPureWriteBitmapRef();

	// 20181219: to avoid the pwBitmap be recycle,the app needs to free it by hand.
	public abstract void freePureWriteBitmap(Bitmap pwBitmap) ;

	// 20180605,add src/dst rect.
	public abstract void setPWBitmap(Bitmap newBitmap, Rect src, Rect dst,
                                     boolean recycle);

	// 20180615,remain old function for compitable.
	public abstract void setPWBitmap(Bitmap newBitmap);

	public abstract void setDrawObjectType(int objType);

	public abstract int getDrawObjectType();

	public void saveBitmap(boolean saveContentBitmap, PWSaveBitmapListener listener);

	public void saveBitmap(PWLSBitmapListener listener);

	// 20180322,add the background matts for pen-write.
	@Deprecated
    public interface  BackGroundMatts {
    	// 20180322,the id of the BackGroundMatts,maybe type+size.
    	public int getWTUnitId();

    	// the draw function when host view update.
    	public void drawAllUnits(Canvas canvas, View hostView);
    }

    @Deprecated
    public void setBgMatts(BackGroundMatts matts);

    @Deprecated
    public BackGroundMatts getBgMatts();

	// 20180402,hsl add for user Matts repaint.
    @Deprecated
	public void registerBgMatts(BackGroundMatts matts);

    @Deprecated
	public void setBackGroupMatts(int type, int dpSize);


    @Deprecated
	public int getBackGroundMattsType();

	public int getAvailableUndo();

	public boolean unDo();

	public int getAvailableRedo();

	public boolean reDo();

	public int getAvailableRepaintStep();

	/**
	 * 20180317,change the parameter to speedType,
	 * the value is RP_SPEED_X1,RP_SPEED_S2,...
	 */
	public boolean repaintStep(int speedType, int startStep, int endStep,
                               int maxDelay, RepaintListener listener);

	public void stopRepaint();

	public boolean repaintOnePoint();

	public boolean emulateLastTouchInput();

	/**
	 * 20180531,add to avoid pw-write at specail Rects.
	 * @param unWriteRect
	 */
	public abstract void addUnWriteRect(Rect unWriteRect);

	public abstract ArrayList<Rect> getUnWriteRectList();

	public abstract void clearUnWriteRectList();


	public Rect getPWListDrawRect();

	/**
	 * 20180626,for handle grap-erase.
	 */
	public void addGrayRect(Rect grayRect);

	public ArrayList<Rect> getGrayRectList();

	public void clearGrayRectList();

	// 20180610,we use a high thread to dispatch Event,so if host view
	// need this event first,the host will need to send the event back to us.
	// handled: weather the host already handle this event.
	public void sendBackEvent(MotionEvent event, boolean stop);

	/**
	 * 20180827: 用于监听手写view收到的 MotionEvent.注意： 这个函数在 手写线程里面调用，因此
	 * 不能在这个函数里面执行太多操作，并且不能在这个函数里面操作UI，比如调用 TextView.setText.
	 * 20181109: 改为新的interface 之后，这个接口放到 View 里面。
	 */
	//public void onPWTouchEvent(MotionEvent event);

	// 20180821,hsl add.
	public abstract void addOnTopView(View v);

	// 20180821,hsl add.
	public abstract void removeOnTopView(View v);


	/**
	 * 20181210: 设置是否手写和输入法同时存在。默认是true。
	 *  如果手写的时候，输入法要自动消失，则需要设置为 false。
	 */
	public void setWritableWhenImeInput(boolean writable);
}
